<template>
  <div style="height:70vh;overflow: auto">
    <vue3-tree-org ref="treeOrgRef" :props="props" :data="data" :define-menus="defineMenus"
      :default-expand-level="expandLevel" center :horizontal="horizontal" :collapsable="collapsable"
      :only-one-node="onlyOneNode" :filter-node-method="filterNodeMethod" :clone-node-drag="cloneNodeDrag"
      :node-add="addNode" :node-delete="delNode" :node-edit="editNode" @on-node-click="onNodeClick"
      @on-node-contextmenu="handleNodeContext">
      <template #default="{ node }">
        <div class="custom-node" :class="{
          'has-link': node.$$data.url,
        }" :style="{ backgroundColor: node.$$data.color }" @mouseenter="hoverNode = node.id"
          @mouseleave="hoverNode = null">
          <div class="node-content">
            <div class="node-name">
              <Icon :icon="node.$$data.icon" class="plus" />
              {{ node.$$data.name }}
            </div>
            <div v-if="node.$$data.title" class="node-title">
              {{ node.$$data.title }}
            </div>
          </div>

          <div v-if="node.$$data.url" class="node-link-hint">
            <el-icon :class="{ 'pulse': hoverNode === node.id }">
              <Link />
            </el-icon>
          </div>
        </div>
      </template>
    </vue3-tree-org>
  </div>
  <ReportViewForm ref="reportDialogRef" @success="getOrgData()" />
</template>

<script lang="ts" name="treeView" setup>
import { ReportViewApi } from '@/api/business/reportview'
import { url } from 'inspector'
import { any } from 'vue-types'
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const ReportViewForm = defineAsyncComponent(() => import('./ReportViewForm.vue'))

// 定义org组件key-value定义
const props = reactive({
  id: 'id',
  pid: 'parentId',
  label: 'name',
  expand: 'expand',
  children: 'children',
  url: 'url'
})


const data = reactive({
  id: '',
  parentId: '',
  name: '',
  icon: '',
  title: '',
  color: '',
  url: ''
})


// 定义org组件右键定义
const defineMenus = reactive([
  { name: '新增', command: 'add' },
  { name: '修改', command: 'edit' },
  { name: '删除', command: 'delete' }
])

const cloneNodeDrag = ref(true)
const collapsable = ref(false)
const expandLevel = ref(2) //默认展开层级
const horizontal = ref(false)
const onlyOneNode = ref(false)
const treeOrgRef = ref()
const reportDialogRef = ref()

/**
 * 过滤节点
 */
const filter = (deptName: string) => {
  treeOrgRef.value.filter(deptName)
}

/**
 * 节点过滤方法
 * @param {string} value 过滤条件
 * @param {object} data 节点数据
 * @returns {boolean} 返回过滤结果
 */
const filterNodeMethod = (value, data) => {
  if (!value) return true
  return data.label.indexOf(value) !== -1
}

/**
 * 处理展开/折叠树
 */
const handleExpand = async () => {
  collapsable.value = !collapsable.value
}

/**
 * 检查节点是否是根租户节点
 * @param {object} node 节点对象
 * @returns {boolean} 如果节点是根租户节点，返回true；否则返回false
 */
const checkNode = (node) => {
  if (node?.id === '0') {
    message.error(t('common.tenantNodeErrorText'))
    return false
  }
  return true
}

/**
 * 当用户左键点击节点
 * @param node
 */
const onNodeClick = (e, node: any) => {
  console.log('左键单击', node)

  // 检查是否存在有效URL
  if (node.url) {
    // 处理URL格式（自动补全http协议）
    const formattedUrl = node.url.startsWith('http') ? node.url : `https://${node.url}`

    // 新窗口打开（带安全限制解除）
    const newWindow = window.open('', '_blank')
    if (newWindow) {
      newWindow.opener = null  // 安全措施
      newWindow.location.href = formattedUrl
    } else {
      console.error('弹出窗口被浏览器阻止，请检查浏览器设置')
    }
  }
}

const handleNodeContext = (event: MouseEvent, nodeData: any, node: any, element: HTMLElement) => {
  // 阻止默认浏览器右键菜单
  event.preventDefault()

  const { clientX, clientY } = e
  const rightFun = new MouseEvent('contextmenu', {
    bubbles: true,
    cancelable: false,
    view: window,
    button: 2,
    buttons: 0,
    clientX,
    clientY
  })
  e.target.dispatchEvent(rightFun)
  console.log('右键点击节点:', nodeData)
}

/**
 * 添加部门
 * @param {object} node 节点对象
 */
const addNode = (node) => {
  reportDialogRef.value.open('create', node?.id)
}

/**
 * 编辑部门
 * @param {object} node 节点对象
 */
const editNode = (node) => {
  if (!checkNode(node)) {
    return
  }
  reportDialogRef.value.open('edit', node?.id)
}

/**
 * 删除部门
 * @param {object} node 节点对象
 */
const delNode = async (node) => {
  if (!checkNode(node)) {
    return
  }

  try {
    // 删除的二次确认
    await message.delConfirm()
    // 发起删除
    await ReportViewApi.deleteReportView(node.id)
    message.success(t('common.delSuccess'))
    // 刷新数据
    await getOrgData()
  } catch (err: any) {

  }

}

/**
 * 查询部门数据
 */
const getOrgData = async () => {
  // 查询当前租户信息
  // const tenant = await getObj(Session.getTenant())
  await ReportViewApi.reportTree().then((res) => {
    //// 执行赋值逻辑
    const rootNode = res[0] // 取第一个节点作为根

    // 1. 把 res[0] 的基本信息赋值给 reactive 对象 data
    Object.assign(data, {
      id: rootNode.id,
      parentId: rootNode.parentId,
      name: rootNode.name,
      icon: rootNode.icon,
      title: rootNode.title,
      color: rootNode.color,
      url: rootNode.url,
    })

    data.children = res[0].children

  })
}

onMounted(() => {
  getOrgData()
})

// 暴露变量
defineExpose({
  getOrgData,
  handleExpand,
  filter
})
</script>



<style>
.tree-container {
  background: linear-gradient(135deg, #f5f7fa 0%, #e4efe9 100%);
  border-radius: 12px;
  padding: 20px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
}

.custom-node {
  background: white;
  border-radius: 10px;
  padding: 14px 18px;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08);
  border: 1px solid #e1e5eb;
  transition: all 0.3s ease;
  position: relative;
  min-width: 180px;
  display: flex;
  flex-direction: column;
}

.custom-node:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 15px rgba(66, 153, 225, 0.25);
  border-color: #c2d9f0;
}

.has-link {
  border-left: 4px solid #4299e1;
  cursor: pointer;
}

.has-link:hover {
  background-color: #f0f7ff;
}

.highlight-node {
  background: linear-gradient(135deg, #ebf4ff 0%, #d5e8ff 100%);
  border: 1px solid #a3c7f7;
}

.node-content {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.node-name {
  font-size: 16px;
  font-weight: 600;
  color: #2d3748;
  align-items: center;
  gap: 8px;
}

.node-title {
  font-size: 13px;
  color: #718096;
  font-style: italic;
  padding-top: 4px;
  border-top: 1px dashed #e2e8f0;
}

.node-icon {
  color: #4299e1;
  font-size: 18px;
}

.node-link-hint {
  position: absolute;
  top: -10px;
  right: -10px;
  background: #4299e1;
  color: white;
  border-radius: 50%;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 5px rgba(66, 153, 225, 0.5);
  transition: all 0.3s ease;
}

/* 链接提示动画 */
.pulse {
  animation: pulse-animation 1.5s infinite;
}

@keyframes pulse-animation {
  0% {
    transform: scale(1);
  }

  50% {
    transform: scale(1.2);
  }

  100% {
    transform: scale(1);
  }
}


::v-deep .vue3-tree-org .tree-org-node__children::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 2px;
  background: #ff4d4f;
  z-index: 1;
}
</style>
